package order

import (
	"context"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"mxshop-api/order-web/api"
	"mxshop-api/order-web/forms"
	"mxshop-api/order-web/global"
	orderpb "mxshop-api/order-web/proto/order/gen/v1"
	"mxshop-api/shared/auth"
	"mxshop-api/shared/utils"
)

type APIOrder struct {
	ID         int32  `json:"id,omitempty"`
	UserId     int32  `json:"user_id,omitempty"`      // 用户ID
	OrderSn    string `json:"order_sn,omitempty"`     // 订单编号
	PayType    uint8  `json:"pay_type,omitempty"`     // 支付方式
	PayTypeStr string `json:"pay_type_str,omitempty"` // 支付方式字符
	Status     uint8  `json:"status,omitempty"`       // 订单状态
	StatusStr  string `json:"status_str,omitempty"`   // 订单状态字符
	Post       string `json:"post,omitempty"`         // 加急
	Total      string `json:"total,omitempty"`        // 总金额
	Address    string `json:"address,omitempty"`      // 地址
	Name       string `json:"name,omitempty"`         // 姓名
	Mobile     string `json:"mobile,omitempty"`       // 电话
	AddTime    string `json:"add_time,omitempty"`
}

func EntityGrpcToAPIOrder(o *orderpb.OrderEntity) *APIOrder {
	return &APIOrder{
		ID:         o.Id,
		UserId:     o.Order.UserId,
		OrderSn:    strconv.FormatInt(o.Order.OrderSn, 10),
		PayType:    uint8(o.Order.PayType),
		PayTypeStr: o.Order.PayType.String(),
		Status:     uint8(o.Order.Status),
		StatusStr:  o.Order.Status.String(),
		Post:       o.Order.Post,
		Total:      utils.PriceInt(o.Order.Total).String(),
		Address:    o.Order.Address,
		Name:       o.Order.Name,
		Mobile:     o.Order.Mobile,
		AddTime:    o.Order.AddTime,
	}
}

func List(c *gin.Context) {
	// 1.获取登录用户的信息
	claims, err := auth.ClaimsFromContext(c)
	if err != nil {
		return
	}

	// 2.获取页码参数
	var pagination forms.Pagination
	err = c.ShouldBindUri(&pagination)
	if err != nil {
		api.HandleValidatorError(c, err)
		return
	}

	var orderFilter = orderpb.OrderFilterRequest{
		Pages:       pagination.Page,
		PagePerNums: pagination.PageSize,
	}

	// 3.根据不同的用户类型去定制不同的过滤条件
	switch claims.RoleID {
	case 1: // 普通用户返回自己的订单
		orderFilter.UserId = int32(claims.ID)
	case 2: // 管理员用户返回所有订单
	default:
		c.Status(http.StatusForbidden)
		return
	}

	orderCli := orderpb.NewOrderServiceClient(global.OrderConn)
	orderListResp, err := orderCli.OrderList(context.Background(), &orderFilter)
	if err != nil {
		api.HandleGrpcErrorToHttp(c, err)
		return
	}

	data := make([]*APIOrder, 0, len(orderListResp.Orders))
	for _, order := range orderListResp.Orders {
		data = append(data, EntityGrpcToAPIOrder(order))
	}

	c.JSON(http.StatusOK, gin.H{
		"total": orderListResp.Total,
		"data":  data,
	})
}

func New(c *gin.Context) {
	/*
		创建订单只是创建,还需要选择支付方式/取消。应该有个payment接口。
		1.选择任意一种支付方式:订单状态改为支付中,则调用所选择的支付方式的API,生成支付链接,并返回给前端,用户进行支付
		2.选择取消:订单状态改为等待用户支付,同时有倒计时超时取消。
	*/
	userID, err := auth.UserIDFromContext(c)
	if err != nil {
		return
	}

	var createForm forms.CreateOrderForm
	err = c.ShouldBind(&createForm)
	if err != nil {
		api.HandleValidatorError(c, err)
		return
	}

	orderCli := orderpb.NewOrderServiceClient(global.OrderConn)
	orderEntityResp, err := orderCli.CreateOrder(context.Background(), &orderpb.CreateOrderRequest{
		UserId:  int32(userID),
		Address: createForm.Address,
		Name:    createForm.Name,
		Mobile:  createForm.Mobile,
		Post:    createForm.Post,
	})
	if err != nil {
		api.HandleGrpcErrorToHttp(c, err)
		return
	}

	c.JSON(http.StatusCreated, EntityGrpcToAPIOrder(orderEntityResp))
}

type APIOrderItem struct {
	ID         int32   `json:"id,omitempty"`
	GoodsID    int32   `json:"goods_id,omitempty"`
	GoodsName  string  `json:"name,omitempty"`
	GoodsImage string  `json:"image,omitempty"`
	GoodsPrice float32 `json:"price,omitempty"`
	Nums       int32   `json:"nums,omitempty"`
}

type APIOrderDetail struct {
	APIOrder
	Goods []*APIOrderItem `json:"goods"`
}

func ItemGrpcToItem(o *orderpb.OrderItemEntity) *APIOrderItem {
	return &APIOrderItem{
		ID:         o.Id,
		GoodsID:    o.GoodsId,
		GoodsName:  o.GoodsName,
		GoodsImage: o.GoodsImage,
		GoodsPrice: float32(o.GoodsPrice / 100),
		Nums:       o.Nums,
	}
}

func Detail(c *gin.Context) {
	// 1.获取登录用户的信息
	claims, err := auth.ClaimsFromContext(c)
	if err != nil {
		return
	}

	// 2.获取订单ID
	var i forms.IDValidator
	err = c.ShouldBindUri(&i)
	if err != nil {
		api.HandleValidatorError(c, err)
		return
	}

	var detailReq = orderpb.OrderDetailRequest{
		OrderId: i.ID,
	}

	// 3.根据不同的用户类型去定制不同的过滤条件
	switch claims.RoleID {
	case 1: // 普通用户返回自己的订单
		detailReq.UserId = int32(claims.ID)
	case 2: // 管理员用户返回所有订单
	default:
		c.Status(http.StatusForbidden)
		return
	}

	orderCli := orderpb.NewOrderServiceClient(global.OrderConn)
	orderDetailResp, err := orderCli.OrderDetail(context.Background(), &detailReq)
	if err != nil {
		api.HandleGrpcErrorToHttp(c, err)
		return
	}

	// 订单信息
	apiOrder := EntityGrpcToAPIOrder(orderDetailResp.Order)

	// 订单商品信息
	goods := make([]*APIOrderItem, 0, len(orderDetailResp.Goods))
	for _, goodsInfo := range orderDetailResp.Goods {
		goods = append(goods, ItemGrpcToItem(goodsInfo))
	}

	c.JSON(http.StatusOK, APIOrderDetail{
		APIOrder: *apiOrder,
		Goods:    goods,
	})
}
